//******************************************************************/
//版本说明:
//V0.1		2019-01-31	11:00	yshao	灯饰控制器PHY通讯顶层
//******************************************************************/
module main_ctrl(
		//输出复位和时钟
		input	wire			resetb,
		input	wire			sclk,

		input	wire	[20:0]	time_us,
		input	wire	[20:0]	sync_us,
		
		//按键和指示灯
		input	wire			key_in,
 		output	wire			led_g,

`ifdef H611
		//Flash接口
		output	wire			flash_CS_n,
		output	wire			flash_SCK,
		output	wire			flash_SI,
		input	wire			flash_SO,

		//PHY配置接口
		output	wire			phy_rst,
		output	wire			phy_mdc,
		inout	tri				phy_mdio,

		//冗余控制信号
		output	wire	[1:0]	device_main,
`endif

		//外部MCU通讯接口
		input	wire			mcu_fpga_ctrl,		//mcu到fpga的模式控制信号

		input	wire			mcu_spi_fpga,		//spi工作在通讯模式		
		input	wire			mcu_spi_clk,
		input	wire			mcu_spi_mosi,
		output	reg				mcu_spi_miso,

		output	wire			spi2_cs,
		output	wire			spi2_clk,
		output	wire			spi2_mosi,

		//PHY通讯接口
		output	wire			sub_mode,
		output	wire	[1:0]	depth_state,
		output	wire	[9:0]	current_depth,
		
		input	wire			input_L9,
		input	wire	[7:0]	phy_state,
		input	wire			redu_flag,
		input	wire			blank_flag,
		input	wire	[1:0]	rec_vendor,

		input	wire			rec_flag_a,
		input	wire			rec_flag,
		input	wire	[7:0]	rec_data,
		input	wire			rec_error,
		input	wire			rec_error_sync,
		
		output 	reg 	[1:0]	force_send,
		output	reg				send_flag,
		output	reg				pre_flag,
		output	reg		[7:0]	send_data,

		//PHY总线接口
		output	wire			init_mode,
		output	wire			set_d_ok,
		output	wire			ext_d_ok,
		output	wire	[31:0]	set_addr,
		output	wire	[7:0]	set_data,
		input	wire	[7:0]	rd_data,
		input	wire	[15:0]	debug_data,
                
		//MCU总线接口
		output	wire			mcu_set_d_ok,
		output	wire			mcu_ext_d_ok,
		output	wire	[31:0]	mcu_set_addr,
		output	wire	[7:0]	mcu_set_data,
		input	wire	[7:0]	mcu_rd_data,
                
		//L9显示数据接口
		output	wire			vs_L9,
		output	wire			ds_L9,
		output	wire	[7:0]	data_L9,
		output	wire			h_start_L9,
		output	wire	[10:0]	h_num_L9,
		output	wire			l2048_mode,
                
		output	wire	[10:0]	h_offset,
		output	wire	[15:0]	state,
		output	wire	[1:0]	color_restore_type,
		output	wire	[7:0]	testmode,
		output	wire	[8:0]	cascade_light,
		
		//Artnet显示数据接口
		output	reg				input_artnet,
		output	wire			ds_a,
		output	wire	[7:0]	data_a,
		output	wire			h_start_a,
		output	wire	[10:0]	h_num_a,
		
		//背板控制接口
		output	wire	[5:0]	device_port,
		input	wire			fpga_dmx_send,
		output	reg				mcu_dmx_ten,

		//SD卡MCU控制接口
		output	wire			mcu_sd_en,
		input	wire			mcu_sd_miso,
		
		//SD发送数据包接口
		input	wire			force_send_play,
		input	wire			send_flag_dis,
		input	wire			pre_flag_dis,
		input	wire	[7:0]	send_data_dis,
		
		//SD卡状态
		input	wire	[7:0]	sd_state,

		//调试接口
		output	wire	[31:0]	tout
		);

//****************************************************************
//		内部信号
//****************************************************************
wire			send_flag_mcu, pre_flag_mcu, send_flag_com, pre_flag_com;
wire	[7:0]	send_data_mcu, send_data_com;                

//Flash相关
wire			mcu_flash_en;
wire			flash_CS_n_fpga, flash_SCK_fpga, flash_SI_fpga, flash_SO_fpga;

//MUC接口相关
wire			mcu_com_miso, mcu_flash_miso;

//显示数据相关
wire    [10:0]  h_total, l_total;

wire			identify_flag;
//**********mcu-fpga**************
wire			op_addr_mask;

wire			spi_rec_flag;
wire	[7:0]	spi_rec_data;
wire			spi_rec_error;
wire	[1:0]	spi_rec_vendor;

wire			spi_send_flag;
wire			spi_send_pre;
wire	[7:0]	spi_send_data;

wire	[15:0]	fpga_state;

wire			read_state_req;
wire	[7:0]	rd_data_a, rd_data_d;
//**********显示和输出**************
wire			artnet_en;
wire	[5:0]	sys_port;
wire	[12:0]	port_start;

wire			vs_out;
wire			ds_b, h_start_b, artnet_flag;
wire	[7:0]	data_b;
wire	[10:0]	h_num_b;

reg				force_send_mcu;
reg		[1:0]	mcu_force_port;

wire	[4:0]	universe_r_addr;
wire	[15:0]	universe_r_data;

//**********调试用信号**********
reg				time_ss;
wire	[7:0]	comm_tout, spi_tout, l9_com_tout;
wire	[15:0]	boot_tout;

//**************************************************************
//			   参数定义
//**************************************************************



//**************************************************************
//			整体控制
//**************************************************************
//********LED指示灯控制********
led_ctrl_01 Led_Ctrl_SV2(
		.resetb(resetb),
		.sclk(sclk),
		
		.time_ms(time_us[10]),
		.time_250ms(time_ss),//time_us[18]),

		.G_black(1'b0),
		.G_flash(rec_flag | send_flag_dis),

		.R_light(1'b0),		//black_mark
		.R_flash(1'b0),		//rec_error_sync

		.G_flash_1st(1'b1),
		.R_flash_1st(1'b0),
		
		.tx_err_en(1'b0),
		
		.nG_led(led_g),
		.nR_led()
		);

//********复位控制********
`ifdef H611
reboot_ctrl_AGM reboot_ctrl(
		.resetb(resetb),
		.sclk(sclk),
		
		.mcu_cmd_d_ok(mcu_ext_d_ok),
		.mcu_cmd_addr(mcu_set_addr),
		.mcu_cmd_data(mcu_set_data),
	        
		.tout(boot_tout)
		);
`else
reboot_ctrl reboot_ctrl(
		.resetb(resetb),
		.sclk(sclk),
		
		.mcu_cmd_d_ok(mcu_ext_d_ok),
		.mcu_cmd_addr(mcu_set_addr),
		.mcu_cmd_data(mcu_set_data),
	        
		.tout(boot_tout)
		);
`endif
		
//********Flash读写控制********
flash_ctrl flash_ctrl(
		//控制选通
		.mcu_flash_en(mcu_flash_en),
		
		//MCU控制信号
		.mcu_spi_cs(mcu_spi_fpga),
		.mcu_spi_clk(mcu_spi_clk),
		.mcu_spi_mosi(mcu_spi_mosi),
		.mcu_spi_miso(mcu_flash_miso),

		//FPGA控制信号
		.flash_CS_n_fpga(flash_CS_n_fpga),
		.flash_SCK_fpga(flash_SCK_fpga),
		.flash_SI_fpga(flash_SI_fpga),
		.flash_SO_fpga(flash_SO_fpga),

`ifdef H611
		//FPGA接口信号
		.flash_CS_n(flash_CS_n),
		.flash_SCK(flash_SCK),
		.flash_SI(flash_SI),
		.flash_SO(flash_SO),
`endif

		.tout()
		);

//**************************************************************
//		   网口输出数据选通
//**************************************************************    
always	@(posedge sclk or negedge resetb)
	if (resetb==0) begin
		force_send_mcu	<= 1'b0;
		mcu_force_port	<= 2'b00;
		end
	else if ((mcu_ext_d_ok == 1) && (mcu_set_addr == 32'h00010300)) begin
		force_send_mcu	<= mcu_set_data[0];
		mcu_force_port	<= mcu_set_data[2:1];
		end

always	@(posedge sclk)
	if (force_send_mcu == 1) begin
		force_send <= mcu_force_port;
		send_flag <= send_flag_mcu;
		pre_flag <= pre_flag_mcu;
		send_data <= send_data_mcu;
		end
	else if (send_flag_mcu == 1) begin
		force_send <= 2'b00;
		send_flag <= 1'b1;
		pre_flag <= pre_flag_mcu;
		send_data <= send_data_mcu;
		end
	else if (send_flag_com == 1)begin
		force_send <= 2'b00;
		send_flag <= 1'b1;
		pre_flag <= pre_flag_com;
		send_data <= send_data_com;
		end
	else if ((force_send_play == 1) || ((input_L9 == 0) && (input_artnet == 0)))begin
		force_send <= 2'b11;
		send_flag <= send_flag_dis;
		pre_flag <= pre_flag_dis;
		send_data <= send_data_dis;
		end 
	else begin
		force_send <= 2'b00;
		send_flag <= 1'b0;
		pre_flag <= 1'b0;
		send_data <= 8'h0;
		end		
	

//**************************************************************
//		PHY通讯包解析
//**************************************************************        
//iColor通讯设置包解析
v8_phy_com_01 phy_comm(
		.resetb(resetb),
		.sclk(sclk),
		.time_1ms_sync(sync_us[10]),
		.sub_mode(sub_mode),
		
		//整体工作控制
		.init_mode(init_mode),

		//级联地址设定
		.depth_state(depth_state),
		.current_depth(current_depth),

		//phy接口
		.rec_vendor(rec_vendor),
		.blank_flag(blank_flag),
		.redu_flag(redu_flag),
		
		.rec_flag(rec_flag),
		.rec_error(rec_error),
		.rec_data(rec_data),
		
		.send_flag(send_flag_com),
		.pre_flag(pre_flag_com),
		.send_data(send_data_com),
		
		//PHY通讯转MCU标志
		.op_addr_mask(op_addr_mask),

		//内部寄存器设置总线
		.set_d_ok(set_d_ok),
		.set_addr(set_addr[15:0]),
		.set_data(set_data),
		
		.ext_d_ok(ext_d_ok),
		.ext_addr(set_addr[31:16]),
		
		//读取返回数据的接口
		.read_state_req(read_state_req),
		.rd_data(rd_data_d),
		.debug_data(debug_data),

		//Flash接口
		.flash_CS_n(flash_CS_n_fpga),
		.flash_SCK(flash_SCK_fpga),
		.flash_SI(flash_SI_fpga),
		.flash_SO(flash_SO_fpga),

		//调试信号接口
		.tout(comm_tout)
		);

//网口反馈数据
assign	rd_data_d = rd_data | rd_data_a;
		
//Artnet包iColor包ARP包转发MCU
//Artnet显示数据包提取
L9_com_ctrl_02 com_ctrl_b(
		.resetb(resetb),
		.sclk(sclk),
		.comm_en(~init_mode),

		.sub_mode(sub_mode),
		.artnet_en(artnet_en),
		.current_depth(current_depth),
		.device_port(device_port),
		
		.rec_flag(rec_flag_a),
		.rec_data(rec_data),
		.rec_error(rec_error),
		
		.time_1ms_sync(sync_us[10]),
		
		.op_addr_mask(op_addr_mask),

		.spi2_cs(spi2_cs),
		.spi2_clk(spi2_clk),
		.spi2_mosi(spi2_mosi),
		
		.universe_r_addr(universe_r_addr),
		.universe_r_data(universe_r_data),
		
		.artnet_flag(artnet_flag),
		.dsout(ds_a),
		.dout(data_a),
		.h_start(h_start_a),
		.h_num(h_num_a),
		
		.tout(l9_com_tout)
		);

//artnet模式有效判断
always @(posedge sclk or negedge resetb)
	if (resetb == 0)
		input_artnet <= 0;
	else if (input_L9 == 1)
		input_artnet <= 0;
	else if (artnet_flag == 1)
		input_artnet <= 1;

//iColor显示数据包提取
L9_data_rec_02 data_rec(
		.resetb(resetb),
		.sclk(sclk),
		
		//网口配置总线
		.set_d_ok(set_d_ok),
		.set_addr(set_addr[15:0]),
		.set_data(set_data),

		//当前端口范围
		.device_port(device_port),
		.port_start(port_start),

		//工作模式控制
		.init_mode(init_mode),
		.black(1'b0),
		
		//多模块共用设置数据输出
		.h_offset(h_offset),
		.h_total(h_total),
		.l_total(l_total),
		.no_vs_set(),
		
		//PHY模块接口
		.mac_flag(rec_flag),
		.mac_data(rec_data),
		.mac_error(rec_error),
		.mac_vendor(rec_vendor),
		
		//显示数据输出
		.vsout(vs_L9),
		.dsout(ds_L9),
		.dout(data_L9),
		.h_start(h_start_L9),
		.h_num(h_num_L9),
		.l2048_mode(l2048_mode),
		
		//显示设置数据输出
		.state(state[7:0]),	
		.state_2(state[15:8]),
		.color_restore_type(color_restore_type),
		.testmode(testmode),
		.cascade_light(cascade_light),
		.sys_port(sys_port),

		//调试用信号输出
		.tout()
		);
		
//**************************************************************
//		  MCU控制接口
//************************************************************** 
//MCU到FPGA的SPI接口
L9_spi_com_01 mcu_comm(
		.resetb(resetb),
		.sclk(sclk),
		.comm_en(~init_mode),
		
		//MCU到FPGA接口	
		.mcu_spi_cs(mcu_spi_fpga),
		.mcu_spi_clk(mcu_spi_clk),
		.mcu_spi_mosi(mcu_spi_mosi),
		.mcu_spi_miso(mcu_com_miso),

		//返回PHY数据包	
		.send_flag(send_flag_mcu),
		.pre_flag(pre_flag_mcu),
		.send_data(send_data_mcu),
		
		//PHY反馈接口
		.set_addr(set_addr),
		.set_d_ok(set_d_ok),
		.set_data(set_data),
		.rd_data(rd_data_a),
		.read_state_req(read_state_req),
		
		//MCU设置总线
		.mcu_set_d_ok(mcu_set_d_ok),
		.mcu_set_addr(mcu_set_addr[15:0]),
		.mcu_set_data(mcu_set_data),
		
		.mcu_ext_d_ok(mcu_ext_d_ok),
		.mcu_ext_addr(mcu_set_addr[31:16]),
		
		//待反馈设备状态
		.mcu_rd_data(mcu_rd_data),
		.fpga_state(fpga_state),
		.phy_state(phy_state),
		.current_depth(current_depth),
		.depth_state(depth_state),
		.sys_port(sys_port),

		//SD卡接口信号
		.mcu_sd_en(mcu_sd_en),
		//和Flash接口	
		.mcu_flash_en(mcu_flash_en),

`ifdef H611
		//PHY配置接口
		.phy_rst(phy_rst),
		.phy_mdc(phy_mdc),
		.phy_mdio(phy_mdio),

		//冗余控制信号
		.device_main(device_main),
`endif

		//universe读接口	
		.universe_r_addr(universe_r_addr),
		.universe_r_data(universe_r_data),
		
		//配置输出
		.sub_mode(sub_mode),
		.identify_flag(identify_flag),
		.artnet_en(artnet_en),
		.device_port(device_port),
		.port_start(port_start),

		//调试信号
		.tout(spi_tout)
		);

//assign	mcu_flash_en = 0;
assign	fpga_state = {sd_state[1], sd_state[0], sd_state[7], input_L9, input_artnet, 1'b0, mcu_flash_en, mcu_sd_en, init_mode};

always @( * )
	if (mcu_sd_en == 1)
		mcu_spi_miso <= mcu_sd_miso;
	else if (mcu_flash_en == 1)
		mcu_spi_miso <= mcu_flash_miso;
	else if (mcu_spi_fpga == 0)
		mcu_spi_miso <= mcu_com_miso;
	else
		mcu_spi_miso <= fpga_dmx_send;
		
//************************************************************/
//		DMX发送信号
//************************************************************/
always @( * )
	if (mcu_sd_en == 1)
		mcu_dmx_ten <= 1;
	else
		mcu_dmx_ten <= mcu_fpga_ctrl;

//************************************************************/
//		调试接口
//************************************************************/
always @(posedge sclk)
	if (identify_flag == 1)
		time_ss <= time_us[16];
	else if (debug_data > 0)
		time_ss <= time_us[20];
	else
		time_ss <= time_us[18];
		
assign	tout = 0;

endmodule


